package controlLayer;

import java.sql.SQLException;
import java.util.List;

import dbLayer.DBClass;
import dbLayer.DBClassIF;
import dbLayer.DBConnection;
import utilLayer.AlreadyExistsException;
import modelLayer.Class;
import modelLayer.Teacher;


/**
 * This class is a control layer class of the MSAS system. It functions as the link between 
 * our database and the interface. This class is limited to working with the Class class,
 * and whichever other classes class is associated with. There is no direct connection between
 * this class and our database.
 * 
 * @author Danny M�lgaard, Anna Kelemen, Jakob Korsgaard
 * 		   
 * @version 1.3.1
 * 					1.3.1: 		Added more extensive documentation. Verified that
 * 								information contained in the Design Class Diagram,
 * 								is in accordance with the information contained in this
 * 								class.
 *					1.3.2:		Try&catch and throws Exception added to the constructor in order to catch
 *								a NullPointerException and to avoid the program from crashing
 *								if there is no connection to the database. 
 *								SQLException to removeClass() added
 */
public class ClassCtr {

	private DBClassIF dbClass;
	
	/**
	 * Constructs an instance of the ClassCtr. Initializes an instance of DBClass.
	 * @throws Exception
	 */
	public ClassCtr() throws Exception {
		try {
			this.dbClass  = new DBClass();
		}
		catch (Exception e) {
			throw new Exception(); 
		}
		
	}
	
	/**
	 * Sends information from the interface on to the database layer, more specifically
	 * helping in the insertion of a new row in the database. Begins a transactions upon
	 * calling the dbLayer method, and rolls it back should anything that could result in dataloss,
	 * or unintended data manipulation occur.
	 * 
	 * @param	name			String			the name of the class
	 * @param	grade			String			the current grade of the class
	 * @param	yearOf			String			the starting year of the class
	 * @param	ct				Teacher			class teacher as a Teacher object
	 * @return	rc				int				count of rows affected by the query execution in the database
	 * @throws					Exception
	 */
	public int createClass(String name, String grade, String yearOf, Teacher ct) throws Exception {

		int rc = -1;
		try {
			DBConnection.startTransaction();
			rc = this.dbClass.insert(name, grade, yearOf, ct);
			DBConnection.commitTransaction();			
		}
		catch (SQLException ex) {
			DBConnection.rollbackTransaction();
			throw new AlreadyExistsException(name);
		}
		catch (Exception e) {
			DBConnection.rollbackTransaction();
		}
		
		return rc;
		
	}
	
	/**
	 * Sends information from the interface on to the database layer, more specifically
	 * helping in the search of an existing row in the database.
	 * 
	 * @param	name				String			the name of the class
	 * @param	retrieveAssociation	boolean			determines if we're to retrieve 
	 * 												associations or not.
	 * @return						Class			returns the class matching the search.
	 */
	public Class findClass(String name, boolean retriveAssociation) {
		
		return dbClass.find(name, retriveAssociation);
		
	}

	/**
	 * Sends information from the interface on to the database layer, more specifically
	 * helping in the search of an existing row in the database.
	 * 
	 * @param	id					int				the id of the class
	 * @param	retrieveAssociation	boolean			determines if we're to retrieve 
	 * 												associations or not.
	 * @return						Class			returns the class matching the search.
	 */
	public Class findClassById(int id, boolean retrieveAssociation) {
		
		return dbClass.findById(id, retrieveAssociation);
		
	}

	/**
	 * Sends information from the interface on to the database layer, more specifically
	 * helping in the search of all existing rows in the database.
	 * 
	 * @param	retrieveAssociation	boolean			determines if we're to retrieve 
	 * 												associations or not.
	 * @return	all					List<Class>		returns a list of classes.
	 */	
	public List<Class> getAll(boolean retrieveAssociation) {
		
		List<Class> all = dbClass.getAll(retrieveAssociation);
		
		return all;
		
	}
	
	/**
	 * Sends information from the interface on to the database layer, more specifically
	 * helping in the renewal of an existing row in the database. Begins a transactions upon
	 * calling the dbLayer method, and rolls it back should anything that could result in data loss,
	 * or unintended data manipulation occur.
	 * 
	 * @param 	c		Class	an instance of Class to be updated
	 * @return 	rc		int		the count of rows changed in the database
	 */
	public int updateClass(Class c) throws Exception {

		int rc = -1;
		try {
			DBConnection.startTransaction();
			rc = dbClass.update(c);
			DBConnection.commitTransaction();
		}
		catch (SQLException ex) {
			DBConnection.rollbackTransaction();
			throw new AlreadyExistsException(c.getClassName());
		}
		catch (Exception e) {
			DBConnection.rollbackTransaction();
		}
		
		return rc;

	}
	
	/**
	 * Sends information from the interface on to the database layer, more specifically
	 * helping in the removal of an existing row in the database. Begins a transactions upon
	 * calling the dbLayer method, and rolls it back should anything that could result in data loss,
	 * or unintended data manipulation occur.
	 * 
	 * @param 	c		Class		an instance on the class which is to be removed.
	 * @return 	rc		int			the count of rows changed in the database
	 * @throws SQLException 
	 */
	public int removeClass(Class c) throws SQLException {
		
		int rc = -1;
		try {
			DBConnection.startTransaction();
			rc = dbClass.remove(c.getId());
			DBConnection.commitTransaction();
		}
		catch (SQLException e) {
			throw new SQLException(e);
		}
		catch (Exception e) {
			DBConnection.rollbackTransaction();
		}

		return rc;

	}

}
